"""
主窗口事件类，执行事件
"""
import os
import subprocess

from TestToolsV2.common.ActivityDatas import activityDatas
from TestToolsV2.common.CheckContent import checkContent
from TestToolsV2.common.CheckForm import checkForm
from TestToolsV2.common.MyConfig import myConfig
from TestToolsV2.data.DataController import dataController
from TestToolsV2.events.BaseEvent import baseEvent
from TestToolsV2.tools.Log import Log
from TestToolsV2.view import MainWindown
from TestToolsV2.common.InterpretingData import interpretingData
from TestToolsV2.common.CheckData import checkDatas

log = Log()


class mainEvents(baseEvent):
    # noinspection PyCompatibility
    def __init__(self, mainWindown: MainWindown, datas: dataController):
        super().__init__(mainWindown)
        self.main: MainWindown = mainWindown  # 主窗口控件类
        self.datas: dataController = datas  # 配置数据管理类
        self.actyDatas: activityDatas = None  # 活动数据缓存类
        self.config: myConfig = None  # 配置数据缓存类
        self.app = None  # 窗体负载对象
        self.__initEvents()
        self.__initDatas()

    def __initDatas(self):
        """
        设置主窗口默认路径值
        """
        self.main.set_SExclPathEdit_text(self.datas.read_mainWindown.get_forkey("defualExcelPath"))

    def __initEvents(self):
        """
        初始窗体化事件绑定
        """
        # 0.菜单栏
        # 绑定菜单栏主题设置 点击事件
        self.set_trigger("panel", self.panelSettingEvent)
        # 绑定菜单栏默认设置 点击事件
        self.set_trigger("setting", self.settingsEvent)
        # 绑定菜单栏颜色设置 点击事件
        self.set_trigger("highColor", self.colorSettingEvent)
        # 绑定菜单栏字体大小设置 点击事件
        self.set_trigger("highSize", self.sizeSettingEvent)
        # 绑定菜单栏EXCEL读取设置 点击事件
        self.set_trigger("excelSetting", self.excelSettingEvent)
        # 绑定菜单栏置顶设置 点击事件
        self.set_trigger("winTop", self.winTopSettingEvent)
        # 1.查询界面
        # 绑定Excel路径输入框 回车事件
        self.set_returnPress("SExclPathEdit", self.sExclPathEdit_RP_Event)
        # 绑定Excel路径输入框 文本变更事件
        self.set_editingFinish("SExclPathEdit", self.sExclPathEdit_TC_Event)
        # 绑定Excel路径选择按钮 点击事件
        self.set_click("SSelectButton", self.sSelectButtonEvent)
        # 绑定活动数据按钮 点击事件
        self.set_click("SActivityButton", self.sActivityButtonEvent)
        # 绑定数据比对详情弹窗按钮 点击事件
        self.set_click("SLookCheckButton", self.sLookCheckButtonEvent)
        # 绑定规划输入框 文本变更事件
        self.set_textChang("SResourceEdit", self.sResourceEditEvent)
        # 绑定基础表输入框 文本变更事件
        self.set_textChang("STargetEdit", self.sTargetEditEvent)

    def set_app(self, app):
        """
        设置主窗体承载的 QApplication 对象
        """
        self.app = app
        self.main.set_panel(self.datas.read_mainWindown.get_forkey("blackPanel"), self.app)

    def set_tempDatas(self, actyDatas: activityDatas, _config: myConfig):
        """
        设置活动缓存合配置缓存
        """
        self.config = _config
        self.actyDatas = actyDatas

    # 1.查询界面
    def sActivityButtonEvent(self):
        """
        活动数据检查 按钮 点击事件监听
        """
        log.Show("活动数据 按钮 点击事件监听", 30, "MainEvents=>SActivityButtonEvent")
        # 初始化缓存数据
        self.actyDatas.set_defual()

        SCostsComboBox_text = self.main.get_SCostsComboBox_text()
        if SCostsComboBox_text == "无兑换消耗":
            self.actyDatas.isCosts = False
        else:
            self.actyDatas.isCosts = True

        # 获取窗体输入数据
        self.actyDatas.reEditText = self.main.get_SResourceEdit_text().strip() # 规划框输入数据
        self.actyDatas.taEditText = self.main.get_STargetEdit_text().strip() # 基础表框输入数据
        self.actyDatas.dirPath = self.main.get_SExclPathEdit_text().strip() # 路径框输入数据
        self.actyDatas.mark = self.datas.mark  # 将标记器赋值给缓存管理

        # 判断是否非文本比对，文本比对无需校验格式
        if not self.main.get_SStrRadioButton_value():
            # 获取 ParametersConfig.json 配置中规划抬头字段名
            self.actyDatas.reTitles = self.datas.read_parameters.get_forkey("reTitles")
            # 获取 ParametersConfig.json 配置中基础表抬头字段名
            self.actyDatas.taTitles = self.datas.read_parameters.get_forkey("taTitles")
            # 将搜索管理类对象赋值给缓存管理
            self.actyDatas.searcher = self.datas.searcher
            # 先进行格式校验，校验不通过，则不往下执行
            _checkForm = checkForm(self.actyDatas)
            # 执行格式校验
            formIsOk = _checkForm.do_checkForm()
            if not formIsOk:
                return

        # 判断是否勾选了规划检查或者文本比对
        if self.main.get_SDataRadioButton_value():  # 勾选了勾选了规划检查
            _intpData = interpretingData(self.actyDatas)
            self.actyDatas.reRewards, self.actyDatas.reCosts = _intpData.do_interpretingData(0)
            self.actyDatas.taRewards, self.actyDatas.taCosts, self.actyDatas.allNumbers = _intpData.do_interpretingData(
                1)
            # 进行规划检查
            _checkDatas = checkDatas(self.actyDatas)
            _checkDatas.do_checkData()
        elif self.main.get_SStrRadioButton_value():  # 勾选了文本比对
            _checkContent = checkContent(self.actyDatas)
            if not _checkContent.do_checkContent():  # 进行文本比对
                self.actyDatas.diffInfo.append('纯文本比对存在【差异】')
            else:
                self.actyDatas.diffInfo.append('纯文本比对无差异内容')
        else:
            pass

        if self.actyDatas.colorKey == 0:  # 标志为0时，说明无差异
            self.main.set_SRGLabel_text("无差异", 0)
        elif self.actyDatas.colorKey == 1:
            self.main.set_SRGLabel_text("有差异 有差异 有差异", 1)

        reLines = self.actyDatas.reEditText.splitlines()
        taLines = self.actyDatas.taEditText.splitlines()
        print("reLines: ",len(reLines))
        print("taLines: ",len(taLines))
        if self.actyDatas.diffIndex:
            # 遍历差异下标，标记差异内容
            for x in self.actyDatas.diffIndex:
                print("x+1 ",x+1)
                index = x + 1
                reLines[index] = self.actyDatas.mark.markT(reLines[index])
                taLines[index] = self.actyDatas.mark.markT(taLines[index])
        # 清空 三个输入框中的数据
        SResourceEdit = self.main.get_component("SResourceEdit")
        STargetEdit = self.main.get_component("STargetEdit")
        SDiffTextEdit = self.main.get_component("SDiffTextEdit")
        SResourceEdit.clear()
        STargetEdit.clear()
        SDiffTextEdit.clear()

        # 设置规划输入框的内容
        SResourceEdit.appendHtml('<br />'.join(reLines))
        # 设置基础表输入框的内容
        STargetEdit.appendHtml('<br />'.join(taLines))
        # 将差异化信息列表内容进行遍历且转换为字符串
        for x in range(len(self.actyDatas.taAllInfo)):
            self.actyDatas.taAllInfo[x] = str(self.actyDatas.taAllInfo[x])
        # 将差异化信息列表合并为完整字符串
        taText = '<br />'.join(self.actyDatas.taAllInfo)
        # 将差异化信息内容设置为差异化信息展示框的内容
        SDiffTextEdit.setHtml(taText.replace("'", "").replace('"', ""))
        # 如果点选了主动弹出详情比对，则弹出该窗口
        if self.main.get_SGoDataCheckBox_value():
            self.actyDatas.showAllInfo(self.main.get_SStrRadioButton_value())

    def sExclPathEdit_RP_Event(self):
        """
        Excel路径 输入框 回车事件监听
        """
        log.Show("Excel路径 输入框 回车事件监听", 30, "MainEvents=>SExclPathEdit_RP_Event")
        # 判断历史路径是否为空
        histryPathList = self.config.histryPath
        if histryPathList:
            # 不为空则添加历史路径
            self.actyDatas.pathDialog.set_pathListWidget_list(histryPathList)
        # 展示历史路径窗口
        self.actyDatas.pathDialog.showDialog()
        # 获取窗口返回结果：确定->返回 1 ，取消-> 返回 0
        if self.actyDatas.pathDialog.get_dialog_result() == 1:
            # 获取用户选择的历史路径，判断是否为空
            item = self.actyDatas.pathDialog.get_pathListWidget_curItem()
            if item:
                # 同步窗口数据类数据以及输入框中地址
                if not self.SetDir(item):
                    self.actyDatas.openDialog.showMessage("无效路径")
                    return

    def sExclPathEdit_TC_Event(self):
        """
        Excel路径 输入框 文本变更事件监听
        """
        log.Show("Excel路径 输入框 文本变更事件监听", 30, "MainEvents=>SExclPathEdit_TC_Event")
        path = self.main.get_SExclPathEdit_text()
        if not self.SetDir(path):
            self.actyDatas.openDialog.showMessage("无效路径")
            return

    def sSelectButtonEvent(self):
        """
        Excel路径选择 按钮 点击事件监听
        """
        log.Show("Excel路径选择 按钮 点击事件监听", 30, "MainEvents=>SSelectButtonEvent")
        # 展示文件夹路径选择框，并获取返回值
        path = self.actyDatas.openDialog.showDirectory()
        if '/' in path:
            path = path.replace('/', '\\')

        if not self.SetDir(path):
            self.actyDatas.openDialog.showMessage("无效路径")
            return
        self.main.set_SExclPathEdit_text(path)

    def sLookCheckButtonEvent(self):
        """
        数据比对详情弹窗 按钮 点击事件
        """
        log.Show("数据比对详情弹窗 按钮 点击事件", 30, "MainEvents=>SLookCheckButtonEvent")
        self.actyDatas.showAllInfo(self.main.get_SStrRadioButton_value())

    def sResourceEditEvent(self):
        """
        规划输入框 文本变更事件
        """
        log.Show("规划输入框 文本变更事件", 30, "MainEvents=>SResourceEditEvent")
        text = self.main.get_SResourceEdit_text()
        if '\t' in text:
            newtext = text.replace('\t', ' ')
            if text == newtext:
                return
            self.main.get_windownUi().SResourceEdit.setPlainText(newtext)

    def sTargetEditEvent(self):
        """
        基础表输入框 文本变更事件
        """
        log.Show("基础表输入框 文本变更事件", 30, "MainEvents=>STargetEditEvent")
        text = self.main.get_STargetEdit_text()
        text.strip()
        target_rewards = self.datas.read_parameters.get_forkey('target_rewards')
        myTa_Reward = "rewards"
        changeKey = False

        if not text:
            return

        if '\t' in text:
            changeKey = True
            text = text.replace('\t', ' ')

        for target_reward in target_rewards:
            if target_reward in text:
                myTa_Reward = target_reward

        if not self.main.get_SStrRadioButton_value():
            if self.actyDatas.isCosts:
                costsRewards = f'costs {myTa_Reward}'
                if self.main.get_SCostsComboBox_text() == "rewards costs":
                    costsRewards = f'{myTa_Reward} costs'

                if myTa_Reward not in text:
                    if 'costs' not in text:
                        text = f'{costsRewards}\n{text}'
                    else:
                        text = text.replace('costs', costsRewards)
                    changeKey = True
                else:
                    if 'costs' not in text:
                        text = text.replace(myTa_Reward, costsRewards)
                        changeKey = True
            else:
                if myTa_Reward not in text:
                    text = f'{myTa_Reward}\n{text}'
                    changeKey = True

        if changeKey:
            textLines = text.splitlines()
            strList = [x.strip() for x in textLines if x.strip()]
            self.main.get_windownUi().STargetEdit.setPlainText('\n'.join(strList))

    # 0.菜单栏设置
    def panelSettingEvent(self, e):
        """
        主题设置 按钮 点击事件监听
        """
        log.Show("主题设置 按钮 点击事件监听", 30, "MainEvents=>PanelSettingEvent")
        blackPanel = e.text()
        self.main.set_panel(blackPanel, self.app)

    def settingsEvent(self):
        """
        默认设置 按钮 点击事件监听
        """
        log.Show("默认设置 按钮 点击事件监听", 30, "MainEvents=>SettingsEvent")
        self.actyDatas.settDialog.setDatas(self.config)
        self.actyDatas.settDialog.showDialog()
        # 获取窗口返回结果：确定->返回 1 ，取消-> 返回 0
        if self.actyDatas.settDialog.get_result() == 1:
            configDict = self.actyDatas.settDialog.getDatas()
            self.datas.read_mainWindown.set_all(configDict)
            self.datas.read_mainWindown.write_dataDict()
            self.actyDatas.openDialog.showMessage('默认配置设置成功,配置在下次打开时生效')

    def colorSettingEvent(self, e):
        """
        高亮颜色 菜单 点击事件监听
        """
        log.Show("高亮颜色 菜单 点击事件监听", 30, "MainEvents=>ColorSettingEvent")
        highColor = e.text()
        if highColor == 'myColor':
            highColor = self.datas.read_mainWindown.get_forkey("highColor")
        else:
            self.config.highColor = highColor
        self.datas.set_mark(highColor, self.config.highSize)

    def sizeSettingEvent(self, e):
        """
        高亮大小 菜单 点击事件监听
        """
        log.Show("高亮大小 菜单 点击事件监听", 30, "MainEvents=>SizeSettingEvent")
        self.config.highSize = e.text()
        self.datas.set_mark(self.config.highColor, self.config.highSize)

    def excelSettingEvent(self, e):
        """
        EXCEL读取格式设置菜单 点击事件监听
        """
        log.Show("EXCEL读取格式设置菜单 点击事件监听", 30, "MainEvents=>ExcelSettingEvent")
        text = e.text()
        if text == 'openSetting':
            from TestToolsV2.data.ConfigType import configType
            subprocess.Popen(['notepad.exe', self.datas.configPath.get_config(configType.reader)])
        elif text == 'reload':
            log.Show("reload", 30, "MainEvents=>ExcelSettingEvent")
            try:
                # 清除 searcher 缓存
                self.datas.searcher.clearDic()
                # 将当前表格路径设置为缓存路径
                self.datas.set_searcher(self.main.get_SExclPathEdit_text())
                # 结果展示在主界面Lable上
                self.main.set_SRGLabel_text("重载成功", 0)
            except Exception as e:
                self.main.set_SRGLabel_text("重载失败 重载失败 重载失败", 1)
                self.actyDatas.openDialog.showMessage(e)

    def winTopSettingEvent(self, e):
        """
        置顶设置 菜单 点击时间监听
        """
        log.Show("置顶设置 菜单 点击时间监听", 30, "MainEvents=>WinTopSettingEvent")
        self.main.set_winTop(e.text())

    def SetDir(self, path, ):
        """
        设置默认搜索路径\n
        :param path: 文件夹绝对路径
        :return: 设置成功返回True
        """

        if not path:
            return False

        if self.main.get_SExclPathEdit_text() == path:
            return True

        if os.path.exists(path):
            searcher = self.datas.searcher
            dirPath = path
            self.main.set_SExclPathEdit_text(path)

            # 判断新路劲是否存在于历史路径中，如果没有，则加入历史路径
            histryPath_list = self.datas.read_mainWindown.get_forkey("histryPath")
            if path not in histryPath_list:
                histryPath_list.append(path)
                self.datas.read_mainWindown.write_dataDict()

            if not searcher.haveDir(dirPath):  # 判断路径是否 未 添加过
                searcher.addDir(dirPath)  # 添加路径到搜索控制台
            else:
                searcher.setDir(dirPath)
            return True
        else:
            return False
